home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UPopup.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  14.3 KB  |  527 lines  |  [TEXT/MPS ]

  1. // UPopup.cp
  2. // Copyright © 1988-1991 by Apple Computer Inc.  All rights reserved.
  3.  
  4. #ifndef __UGEOMETRY__
  5. #include <UGeometry.h>
  6. #endif
  7.  
  8. #ifndef __CONTROLS__
  9. #include <Controls.h>
  10. #endif
  11.  
  12. #ifndef __RESOURCES__
  13. #include <Resources.h>
  14. #endif
  15.  
  16. #ifndef __TOOLUTILS__
  17. #include <ToolUtils.h>
  18. #endif
  19.  
  20. #ifndef __UMACAPPUTILITIES__
  21. #include <UMacAppUtilities.h>
  22. #endif
  23.  
  24. #ifndef __UMACAPPGLOBALS__
  25. #include <UMacAppGlobals.h>
  26. #endif
  27.  
  28. #ifndef __UFAILURE__
  29. #include <UFailure.h>
  30. #endif
  31.  
  32. #ifndef __UMENUMGR__
  33. #include <UMenuMgr.h>
  34. #endif
  35.  
  36. #ifndef __UPOPUP__
  37. #include <UPopup.h>
  38. #endif
  39.  
  40. //--------------------------------------------------------------------------------------------------
  41. const short kMAPopupRsrcID = 128;                // The rsrc id of the Popup CDEF supplied with MacApp.
  42.  
  43. //--------------------------------------------------------------------------------------------------
  44.  
  45. // The following data structure is a private data structure used by the popup CDEF. It lives as
  46. // a privHdl off the control handle's contrlData field. The first two fields of the private data
  47. // structure are "public" but the rest are private.
  48. struct popupPrivateData
  49. {
  50.     MenuHandle mHandle;                            // the popup's menu handle 
  51.     short mID;                                    // the popup's menu id 
  52.     long mLastResult;
  53.     SignedByte* mPrivate;
  54. };
  55.  
  56.  
  57. typedef popupPrivateData* popupPrivateDataPtr;
  58. typedef popupPrivateDataPtr* popupPrivateDataHandle;
  59.  
  60. //--------------------------------------------------------------------------------------------------
  61.  
  62. ResType pUseResType;
  63.  
  64. //--------------------------------------------------------------------------------------------------
  65. #pragma segment DlgOpen
  66.  
  67. pascal void TPopup::Initialize(void)            // override 
  68. {
  69.     inherited::Initialize();
  70.  
  71.     fDefChoice = mPopupHit;
  72.  
  73.     fItemOffset = 0;                            // ??? Is this the best default? 
  74. }
  75.  
  76. //--------------------------------------------------------------------------------------------------
  77. #pragma segment DlgOpen
  78.  
  79. pascal void TPopup::IPopup(TView* itsSuperView,
  80.                            const VPoint& itsLocation,
  81.                            const VPoint& itsSize,
  82.                            SizeDeterminer itsHSizeDet,
  83.                            SizeDeterminer itsVSizeDet,
  84.                            short itsMenuID,
  85.                            // rsrc ID of 'MENU' or 'CMNU' rsrc 
  86.                            short itsCurrentItem,
  87.                            short itsItemOffset,
  88.                            // width of the popup title area 
  89.                            const Str255& itsLabel,
  90.                            /* Style */ short itsStyle,
  91.                            // title's style 
  92.                            short itsJust,
  93.                            // title's justification 
  94.                            Boolean useAddResMenu,
  95.                            // TRUE if want to AddResMenu (can use
  96.                            // this option iff menuID != kNoResource)
  97.                            ResType useAddResMenuResType)    // used if useAddResMenu is TRUE
  98.  
  99. {
  100.     short itsProcID = popupMenuProc;
  101.     
  102.     if (!gConfiguration.hasPopupCDEF)
  103.         itsProcID = 16 * kMAPopupRsrcID;            // use MAPopup if System one isn't present
  104.  
  105.     itsProcID += popupUseWFont;                        // always use window font
  106.  
  107.     pUseResType = '    ';
  108.     if (useAddResMenu)
  109.     {
  110.         itsProcID += popupUseAddResMenu;// set if popup uses AddResMenu 
  111.         pUseResType = useAddResMenuResType;
  112.     }
  113.  
  114.     // initialize the popup 
  115.     ICtlMgr(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, GetPopupTitleStyle(itsStyle, itsJust), itsMenuID, itsItemOffset, itsProcID);
  116.  
  117.     // set up the rest of the instance variables 
  118.     fItemOffset = itsItemOffset;
  119.  
  120.     // SetCurrentItem(itsCurrentItem, kDontRedraw);
  121.     fItsCurrentItem = itsCurrentItem;
  122. }
  123.  
  124. //--------------------------------------------------------------------------------------------------
  125. #pragma segment DlgOpen
  126.  
  127. pascal void TPopup::IRes(TDocument* ,
  128.                          TView* itsSuperView,
  129.                          Ptr& itsParams)        // override 
  130. {
  131.     Str255    itsLabel("");
  132.     short    itsPopupTitleStyle = popupTitleNoStyle;
  133.     short    itsProcID;
  134.     short    itsMenuID;
  135.     short    itsItemOffset;
  136.     short    itsCurrentItem;
  137.     MenuHandle itsMenuHandle = NULL;
  138.  
  139.     inherited::IRes(NULL, itsSuperView, itsParams);
  140.     
  141.     {
  142.         PopupTemplate& templateData = *((PopupTemplate *) itsParams);
  143.     
  144.         itsMenuID = templateData.rsrcID;
  145.         itsItemOffset = templateData.itemOffset;
  146.         itsProcID = popupMenuProc + popupUseWFont;    // always use window font
  147.         itsCurrentItem = templateData.currentItem;
  148.     
  149.         pUseResType = '    ';                // !!! fix this when the PopupTemplate is updated
  150.  
  151.         // uncomment this when the PopupTemplate is updated
  152.         // itsPopupTitleStyle = GetPopupTitleStyle(templateData.itsStyle, templateData.itsJust);
  153.     }
  154.  
  155.     // get the menu label
  156.     itsMenuHandle = MAGetMenu(itsMenuID);
  157.     if (itsMenuHandle)
  158.         CopyStr255((**itsMenuHandle).menuData, (Ptr)  &itsLabel);
  159.  
  160.     // initialize the popup 
  161.     VRect itsBounds;
  162.     this->ControlArea(itsBounds);
  163.     this->CreateCMgrControl(itsBounds, itsLabel, itsPopupTitleStyle, itsMenuID, itsItemOffset, itsProcID);
  164.  
  165.     // set up the rest of the instance variables 
  166.     fItemOffset = itsItemOffset;
  167.  
  168.     // SetCurrentItem(itsCurrentItem, kDontRedraw);
  169.     fItsCurrentItem = itsCurrentItem;
  170.  
  171.     OffsetPtr(itsParams, sizeof(PopupTemplate));
  172. }
  173.  
  174. //--------------------------------------------------------------------------------------------------
  175. #pragma segment DlgOpen
  176.  
  177. pascal short TPopup::GetPopupTitleStyle(/* Style */ short itsStyle,
  178.                                         short itsJust)
  179. {
  180.     short popupTitleStyle;
  181.  
  182.     // set up justification value
  183.     if (itsJust == teJustCenter)
  184.         popupTitleStyle = popupTitleCenterJust;
  185.     else if (itsJust == teJustRight)
  186.         popupTitleStyle = popupTitleRightJust;
  187.     else
  188.         popupTitleStyle = popupTitleLeftJust;        // default value.
  189.  
  190.     // set up style value
  191.     if (itsStyle == normal)
  192.         popupTitleStyle += popupTitleNoStyle;
  193.     else
  194.     {
  195.         if (IN(itsStyle, bold))
  196.             popupTitleStyle += popupTitleBold;
  197.         if (IN(itsStyle, italic))
  198.             popupTitleStyle += popupTitleItalic;
  199.         if (IN(itsStyle, underline))
  200.             popupTitleStyle += popupTitleUnderline;
  201.         if (IN(itsStyle, outline))
  202.             popupTitleStyle += popupTitleOutline;
  203.         if (IN(itsStyle, shadow))
  204.             popupTitleStyle += popupTitleShadow;
  205.         if (IN(itsStyle, condense))
  206.             popupTitleStyle += popupTitleCondense;
  207.         if (IN(itsStyle, extend))
  208.             popupTitleStyle += popupTitleExtend;
  209.     }
  210.  
  211.     return popupTitleStyle;
  212. }
  213.  
  214. //--------------------------------------------------------------------------------------------------
  215. #pragma segment DlgOpen
  216.  
  217. pascal void TPopup::CreateCMgrControl(const VRect& itsBounds,
  218.                                       const Str255& itsTitle,
  219.                                       long itsVal,
  220.                                       long itsMin,
  221.                                       long itsMax,
  222.                                       short itsProcID)// override 
  223. {
  224.     GrafPtr itsPort;
  225.     ControlHandle aCMgrControl;
  226.     FailInfo fi;
  227.     TextStyle aTextStyle;
  228.  
  229.     itsPort = GetGrafPort();
  230.     if (!itsPort)
  231.         itsPort = gWorkPort;
  232.  
  233.     // set the textstyle to use when creating the popup 
  234.     // aTextStyle = fTextStyle;
  235.     // SetPortTextStyle(aTextStyle);
  236.  
  237.     // create the control 
  238.     if (fi.Try())
  239.     {
  240.         Rect qdRect;
  241.         this->ViewToQDRect(itsBounds, qdRect);
  242.         aCMgrControl = NewControl(itsPort, qdRect, itsTitle, FALSE, (short)itsVal, (short)itsMin, (short)itsMax, itsProcID, ((long)pUseResType));
  243.         FailNIL(aCMgrControl);
  244.         fi.Success();
  245.     }
  246.     else    // Recover
  247.     {
  248.         this->Free();
  249.         fi.ReSignal();
  250.     }
  251.  
  252.     SetCRefCon(aCMgrControl, ((long)this));    // Set refCon here, it has a special value at
  253.     // NewControl time - the ResType for the case
  254.     // in which the popup's variation code has
  255.     // popupUseAddResMenu.
  256.  
  257.     // Keep control off Window's control list b/c the Window Mgr adds the regions of controls in
  258.     // the control list to the update region (see NOTE under DrawControls in Inside Mac volume I)
  259.     // generating an update event.
  260.  
  261.     ((WindowPeek)itsPort)->controlList = (*((WindowPeek)itsPort)->controlList)->nextControl;
  262.  
  263.     fCMgrControl = aCMgrControl;
  264.     DimState(fDimmed, kDontRedraw);
  265.  
  266.     SetCMgrVisibility(itsPort != gWorkPort);
  267. }
  268.  
  269. //--------------------------------------------------------------------------------------------------
  270. #pragma segment DlgRes
  271.  
  272. pascal TObject* TPopup::Clone(void)                // override 
  273. {
  274.     TPopup* aPopup = (TPopup *)(inherited::Clone());
  275.  
  276.     return aPopup;
  277. }
  278.  
  279. //--------------------------------------------------------------------------------------------------
  280. #pragma segment MAWriteRes
  281.  
  282. pascal void TPopup::WRes(ViewRsrcHandle theResource,
  283.                          Ptr& itsParams)        // override 
  284. {
  285.     inherited::WRes(theResource, itsParams);
  286.     // !!! needs to be fleshed out
  287. }
  288.  
  289. //--------------------------------------------------------------------------------------------------
  290. #pragma segment MAWriteRes
  291.  
  292. pascal void TPopup::WriteRes(ViewRsrcHandle theResource,
  293.                              Ptr& itsParams)    // override 
  294. {
  295.     gWResSignature = 'popp';
  296.     gWResType = "TPopup";
  297.     WRes(theResource, itsParams);
  298. }
  299.  
  300. //--------------------------------------------------------------------------------------------------
  301. #pragma segment DlgRes
  302.  
  303. pascal void TPopup::Draw(const VRect& area)        // override 
  304. {
  305.     TextStyle aTextStyle;
  306.  
  307.     this->SetCurrentItem(fItsCurrentItem, kDontRedraw);
  308.  
  309.     // set the textstyle to use when creating the popup 
  310.     aTextStyle = fTextStyle;
  311.     SetPortTextStyle(aTextStyle);
  312.  
  313.     inherited::Draw(area);
  314. }
  315.  
  316.  
  317. //--------------------------------------------------------------------------------------------------
  318. #pragma segment DlgRes
  319.  
  320. pascal void TPopup::DoMouseCommand(VPoint& theMouse,
  321.                                    TToolboxEvent* event,
  322.                                    Point hysteresis)// override 
  323. {
  324.     TextStyle aTextStyle;
  325.  
  326.     // set the textstyle to use when creating the popup 
  327.     aTextStyle = fTextStyle;
  328.     SetPortTextStyle(aTextStyle);
  329.  
  330.     inherited::DoMouseCommand(theMouse, event, hysteresis);
  331.     
  332.     fItsCurrentItem = this->GetCurrentItem();
  333. }
  334.  
  335. //--------------------------------------------------------------------------------------------------
  336. #pragma segment DlgRes
  337.  
  338. pascal void TPopup::AttachMenuHandle(MenuHandle itsMenuHandle)
  339. {
  340.     MenuHandle currentMenuHandle;
  341.  
  342.     // first, a quick safety check to make sure that we do nothing if we are trying to install
  343.     // a menu that is already installed
  344.     currentMenuHandle = GetMenuHandle();
  345.     if (currentMenuHandle != itsMenuHandle)
  346.     {
  347.         if (currentMenuHandle)                    // first, release the old menuhandle 
  348.         {
  349.             // There are 3 cases that we need to account for here:
  350.             //    1. if fMenuHandle is a converted 'CMNU' resource    => leave MenuHandle alone;
  351.             //    2. if fMenuHandle is a 'MENU' resource                 => call ReleaseResource;
  352.             //    3. if fMenuHandle is a menu created with NewMenu    => call DisposeMenu.
  353.             // N.B.: you should never call GetMenu to create the MenuHandle, instead call MAGetMenu.
  354.             if (IsManagedMenu(currentMenuHandle))// case 1
  355.                 ;                                // do nothing
  356.             else if (IsAResource((Handle)currentMenuHandle))// case 2 
  357.                 ReleaseResource((Handle)currentMenuHandle);
  358.             else                                // case 3 
  359.                 DisposeMenu(currentMenuHandle);
  360.             currentMenuHandle = NULL;
  361.         }
  362.  
  363.         // set the menu handle in  the popup's private storage 
  364.         if (fCMgrControl && ((*fCMgrControl)->contrlData))
  365.         {
  366.             (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mHandle = itsMenuHandle;
  367.             (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mID = (*itsMenuHandle)->menuID;
  368.  
  369.             // set up the control's needed values 
  370.             SetMin(1, kDontRedraw);                // min == 1 always 
  371.             if (itsMenuHandle)                    // max == num items in menu 
  372.                 SetMax(CountMItems(itsMenuHandle), kDontRedraw);
  373.             else
  374.                 SetMax(0, kDontRedraw);
  375.             SetVal(1, kDontRedraw);                // val == current item 
  376.         }
  377.     }
  378. }
  379.  
  380. //--------------------------------------------------------------------------------------------------
  381. #pragma segment DlgRes
  382.  
  383. pascal MenuHandle TPopup::GetMenuHandle(void)
  384. {
  385.     if (fCMgrControl && (*fCMgrControl)->contrlData)
  386.         return (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mHandle;
  387.     else
  388.         return NULL;
  389. }
  390.  
  391. //--------------------------------------------------------------------------------------------------
  392. #pragma segment DlgRes
  393.  
  394. pascal CmdNumber TPopup::GetCurrentCommand(void)
  395. {
  396.     return CmdFromMenuItem(GetMenuID(), GetCurrentItem());
  397. }
  398.  
  399. //--------------------------------------------------------------------------------------------------
  400. #pragma segment DlgRes
  401.  
  402. pascal short TPopup::GetCurrentItem(void)
  403. {
  404.     long lastResult;
  405.     
  406.     lastResult = (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mLastResult;
  407.     if (lastResult == 0)
  408.     {
  409.         if (!fCMgrControl)
  410.             return 1;
  411.         else
  412.             return GetCtlValue(fCMgrControl);
  413.     }
  414.     else
  415.         return LoWord(lastResult);
  416. }
  417.  
  418. //--------------------------------------------------------------------------------------------------
  419. #pragma segment DlgRes
  420.  
  421. pascal void TPopup::GetItemText(short item,
  422.                                 Str255& theText)
  423. {
  424.     MenuHandle itsMenuHandle;
  425.  
  426.     theText = "";
  427.     itsMenuHandle = GetMenuHandle();
  428.     if (itsMenuHandle)
  429.         GetItem(itsMenuHandle, item, theText);
  430. }
  431.  
  432. //--------------------------------------------------------------------------------------------------
  433. #pragma segment DlgRes
  434.  
  435. pascal short TPopup::GetMenuID(void)
  436. {
  437.     MenuHandle itsMenuHandle;
  438.     long lastResult;
  439.     
  440.     lastResult = (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mLastResult;
  441.     if (lastResult == 0)
  442.     {
  443.         itsMenuHandle = GetMenuHandle();
  444.         if (!itsMenuHandle)
  445.             return kNoResource;
  446.         else
  447.             return (*itsMenuHandle)->menuID;
  448.     }
  449.     else
  450.         return HiWord(lastResult);
  451. }
  452.  
  453. //--------------------------------------------------------------------------------------------------
  454. #pragma segment DlgRes
  455.  
  456. pascal short TPopup::GetNumberOfItems(void)
  457. {
  458.     if (fCMgrControl)
  459.         return GetCtlMax(fCMgrControl);
  460.     else
  461.         return 0;
  462. }
  463.  
  464. //--------------------------------------------------------------------------------------------------
  465. #pragma segment DlgRes
  466.  
  467. pascal short TPopup::GetRsrcID(void)
  468. {
  469.     return GetMenuID();
  470. }
  471.  
  472. //--------------------------------------------------------------------------------------------------
  473. #pragma segment DlgRes
  474.  
  475. pascal void TPopup::GetTitle(Str255& title)
  476. {
  477.     title = "";
  478.     if (fCMgrControl)
  479.         GetCTitle(fCMgrControl, title);
  480. }
  481.  
  482. //--------------------------------------------------------------------------------------------------
  483. #pragma segment DlgRes
  484.  
  485. pascal void TPopup::SetCurrentItem(short item,
  486.                                    Boolean redraw)
  487. {
  488.     if (fCMgrControl)
  489.         SetCtlValue(fCMgrControl, item);
  490.     if (redraw)
  491.         ForceRedraw();
  492. }
  493.  
  494. //--------------------------------------------------------------------------------------------------
  495. #pragma segment DlgRes
  496.  
  497. pascal void TPopup::SetPopup(MenuHandle itsMenuHandle,
  498.                                       short itsCurrentItem,
  499.                                       Boolean redraw)
  500. {
  501.     AttachMenuHandle(itsMenuHandle);
  502.     SetCurrentItem(itsCurrentItem, redraw);
  503.     if (redraw)
  504.         ForceRedraw();
  505. }
  506.  
  507. //--------------------------------------------------------------------------------------------------
  508. #pragma segment DlgRes
  509.  
  510. pascal void TPopup::SetTitle(const Str255& title)
  511. {
  512.     if (fCMgrControl)
  513.         SetCTitle(fCMgrControl, title);
  514. }
  515.  
  516. //--------------------------------------------------------------------------------------------------
  517. #pragma segment DlgFields
  518.  
  519. pascal void TPopup::Fields(TObject* obj)        // override 
  520. {
  521.     obj->DoToField("TPopup", (Ptr)NULL, bClass);
  522.  
  523.     inherited::Fields(obj);
  524. }
  525.  
  526.  
  527.